package dexter.net.node;

import java.sql.Timestamp;
import java.util.Hashtable;

import dexter.core.host.HostAddress;
import dexter.net.Bus;
import dexter.net.msg.BusMessage;
import dexter.testing.Logger;

public abstract class AbstractNode {
	
    private Bus bus;
	private String context;
	private HostAddress localHH;
	private Hashtable<String, Object> props;
	
	public AbstractNode(String context, HostAddress localHH, Hashtable<String, Object> props) {
		this.context = context;
		this.logger = new Logger();
		this.localHH = localHH;
		this.bus = new Bus(this);
		this.props = props;
	}
	
	public void setBus(Bus bus){
		this.bus = bus;
	}
	
	public Bus getBus() {
		return bus;
	}
	
	public HostAddress getHostAddress() {
		return localHH;
	}
	
	public void close() {
		bus.close();
	}
    public abstract void messageArrive(BusMessage msg);
	
	/*****     TEST     ******/
	
	public void send(HostAddress host, BusMessage msg) {
	   msg.setContext(context);
	   msg.incNumHops();
	   getBus().send(host,msg);
	}
	
	private long numHops = 0;
	private long numMessages = 0;
	
	public void isDelivery(BusMessage msg) {
		numHops+=msg.getNumHops();
		numMessages++;
	}
	
	public long getNumHops() {
		return numHops;
	}

	public long getNumMessages() {
		return numMessages;
	}
	
	public float getNumHopsAvg() {
		if (numMessages>0) return numHops/numMessages;
		else return 0;
	}
	/******    LOGGER   ******/ 
	
	private Logger logger;

	public void log (String txt) {		
      logger.log(getPrompt(),txt);
	}

	public void log (Exception e) {
		logger.error(getPrompt(),e);
	}
	
	private String getPrompt() {
		Timestamp date = new Timestamp(System.currentTimeMillis());
		//TODO: TIME to STRING
		return context+"> "+date+" : ";
	}
	
	public Logger getLog() {
		return logger;
	}
	
	public Hashtable<String,Object> getConfiguration() {
		return props;
	}
	
}
